package com.duobaoyu.dby.supply.message.listener.hander.refund;

import com.alibaba.fastjson.JSON;
import com.duobaoyu.dby.channel.adapter.enums.biz.refund.AfterSaleStatusEnum;
import com.duobaoyu.dby.supply.biz.constant.OperateSourceConstants;
import com.duobaoyu.dby.supply.biz.exception.SupplyChainBizException;
import com.duobaoyu.dby.supply.biz.producer.constant.SupplyChainMQConstants;
import com.duobaoyu.dby.supply.biz.producer.message.AfterStateCheckSyncMessage;
import com.duobaoyu.dby.supply.biz.service.refund.AfterSaleService;
import com.duobaoyu.dby.supply.biz.service.refund.AfterSaleStateMachine;
import com.duobaoyu.dby.supply.common.biz.bo.refund.AfterSaleOutBO;
import com.duobaoyu.dby.supply.common.biz.bo.refund.AfterSaleStateContext;
import com.duobaoyu.dby.supply.core.dinger.annotation.DingerTalk;
import com.duobaoyu.dby.supply.core.rocketmq.handler.AbstractClusterMessageHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Created by shuming on 2023/10/31 16:23
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class OrderCancelSuccessAfterSaleMessageHandler extends AbstractClusterMessageHandler<AfterStateCheckSyncMessage> {

    private final AfterSaleService afterSaleService;

    private final AfterSaleStateMachine afterSaleStateMachine;

    @Override
    public String getTopic() {
        return SupplyChainMQConstants.SupplyChainTopic.SUPPLY_CHAIN_ADMIN_TOPIC;
    }

    @Override
    public String getTag() {
        return SupplyChainMQConstants.SupplyChainTopic.AfterSaleTag.AFTER_SALES_STATE_CHECK;
    }

    @Override
    @DingerTalk(title = "订单取消成功售后消息Consumer")
    public boolean messageHandler(AfterStateCheckSyncMessage message, MessageExt messageExt) {
        try {
            String orderSn = message.getOrderSn();
            AfterSaleOutBO afterSale = afterSaleService.queryAppliedAutoCancelAfterSale(orderSn);
            if (Objects.isNull(afterSale)) {
                if(log.isDebugEnabled()) {
                    log.debug("no auto cancel afterSale for orderSn = {}", orderSn);
                }
                return true;
            }

            List<AfterSaleStateContext.AfterSaleUpdateItemInfo> afterSaleUpdateItems = afterSale.getItems().stream().map(e -> {
                AfterSaleStateContext.AfterSaleUpdateItemInfo afterSaleUpdateItem = new AfterSaleStateContext.AfterSaleUpdateItemInfo();
                afterSaleUpdateItem.setSkuCode(e.getSkuCode());
                afterSaleUpdateItem.setChannelFreightActualRefundAmount(e.getFreightApplyRefundAmount());
                afterSaleUpdateItem.setChannelActualRefundAmount(Optional.ofNullable(e.getApplyRefundAmount()).orElse(BigDecimal.ZERO));
                return afterSaleUpdateItem;
            }).collect(Collectors.toList());

            AfterSaleStateContext context = new AfterSaleStateContext();
            context.setAfterSale(afterSale);
            context.setCurrentAfterSaleStatus(AfterSaleStatusEnum.COMPLETED.getValue());
            context.setOperateSource(OperateSourceConstants.OPERATION_CHANNEL);
            context.setChangeContentOperate(AfterSaleStateContext.ChangeContentOperate.builder()
                    .afterSaleItemInfoList(afterSaleUpdateItems)
                    .channelActualRefundAmount(afterSaleUpdateItems.stream()
                            .map(AfterSaleStateContext.AfterSaleUpdateItemInfo::getChannelActualRefundAmount).reduce(BigDecimal.ZERO, BigDecimal::add))
                    .channelActualRefundAmount(afterSaleUpdateItems.stream()
                            .map(AfterSaleStateContext.AfterSaleUpdateItemInfo::getChannelFreightActualRefundAmount).reduce(BigDecimal.ZERO, BigDecimal::add))
                    .build());
            Boolean result = afterSaleStateMachine.exe(context);
            if (!result) {
                log.error("update afterSale fail param = {}", JSON.toJSONString(context));
                SupplyChainBizException.fail("update afterSale fail orderSn = " + orderSn);
            }
        } catch (Exception e) {
            log.warn("订单取消成功售后消息Consumer消息消费异常,msgId={},param = {}", messageExt.getMsgId(), JSON.toJSONString(message), e);
            return false;
        }
        return true;
    }
}
